package com.cg.design.depthdesign.command.editor;

import com.cg.design.depthdesign.command.commands.*;

import javax.swing.*;
import java.awt.*;

/**
 * 文字编辑器的 GUI 编辑器类包含实际的文本编辑操作。
 * <p>
 * 它会担任接收者的角色：最后所有命令都会将执行工作委派给编辑器的方法。
 *
 * @program: LeetCode->Editor
 * @author: cg
 * @create: 2022-04-05 18:12
 **/
public class Editor {
    /**
     * 文本输入框
     */
    public JTextArea textField;
    /**
     * 剪切板
     */
    public String clipboard;
    /**
     * 命令历史
     */
    private final CommandHistory history = new CommandHistory();

    /**
     * 初始化
     */
    public void init() {
        JFrame frame = new JFrame("Text editor (type & use buttons!)");
        JPanel content = new JPanel();
        frame.setContentPane(content);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
        textField = new JTextArea();
        textField.setLineWrap(true);
        content.add(textField);
        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JButton ctrlC = new JButton("Ctrl+C");
        JButton ctrlX = new JButton("Ctrl+X");
        JButton ctrlV = new JButton("Ctrl+V");
        JButton ctrlZ = new JButton("Ctrl+Z");
        Editor editor = this;
        ctrlC.addActionListener(e -> executeCommand(new CopyCommand(editor)));
        ctrlX.addActionListener(e -> executeCommand(new CutCommand(editor)));
        ctrlV.addActionListener(e -> executeCommand(new PasteCommand(editor)));
        ctrlZ.addActionListener(e -> undo());
        buttons.add(ctrlC);
        buttons.add(ctrlX);
        buttons.add(ctrlV);
        buttons.add(ctrlZ);
        content.add(buttons);
        frame.setSize(450, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    /**
     * 执行命令
     *
     * @param command
     */
    private void executeCommand(Command command) {
        if (command.execute()) {
            history.push(command);
        }
    }

    /**
     * 撤销命令
     */
    private void undo() {
        if (history.isEmpty()) {
            return;
        }
        Command command = history.pop();
        if (command != null) {
            command.undo();
        }
    }

}
